/**
 * Created by Ng on 2023/10/26
 */

import axios from 'axios'
import { getToken, getLoginMethod } from '@/utils'

/**
 * @description 初始化配置 axios
 */
export const request = axios.create({
  timeout: 60000,
  baseURL: import.meta.env.VITE_BASE_API,
})

/**
 * @description 添加请求拦截器
 */
request.interceptors.request.use(
  // 请求成功
  function (config) {
    // 处理不需要 token 的请求
    if (config.isNoNeedToken) {
      return config
    }
    // 处理需要 token 的请求
    let tokenItem = getToken()
    let { token } = tokenItem
    if (tokenItem) {
      config.headers['X-Token'] = token
    }
    config.headers['X-Type'] = getLoginMethod()

    // 加上 token，认证方案: JWT Bearer
    config.headers.Authorization = config.headers.Authorization || 'Bearer ' + token
    return config
  },
  // 请求失败
  function (error) {
    if (!error || !error.request) {
      let code = error?.code
      let message = resolveResError(code, error.message)
      window.onmessage?.error(message)
      return Promise.reject({ code, message, error })
    }
    return Promise.reject(error)
  }
)

/**
 * @description 添加响应拦截器
 */
request.interceptors.response.use(
  // 响应成功
  function (response) {
    // 处理不同的 response.headers
    let { data, status, config, statusText } = response
    if (data?.code !== 200) {
      if (!data.code) {
        return Promise.resolve(data)
      }
      let code = data?.code ?? status
      // 根据 code 处理对应的操作，并返回处理后的 message
      let message = resolveResError(code, data?.message ?? statusText)
      // 是否不需要错误提醒
      !config.isNoNeedTip && window.onmessage?.error(message)
      return Promise.reject({ code, message, error: data || response })
    }
    return Promise.resolve(data)
  },
  // 响应失败
  function (error) {
    if (!error || !error.response) {
      let code = error?.code
      // 根据 code 处理对应的操作，并返回处理后的 message
      let message = resolveResError(code, error.message)
      window.onmessage?.error(message)
      return Promise.reject({ code, message, error })
    }
    let { data, status, config } = error.response
    let code = data?.code ?? status
    let message = resolveResError(code, data?.message ?? error.message)
    // 是否不需要错误提醒
    !config?.isNoNeedTip && window.onmessage?.error(message)
    return Promise.reject({ code, message, error: error.response?.data || error.response })
  }
)

/**
 * @description 服务器错误处理
 * @param {Number} code 
 * @param {String} message 
 * @returns {String}
 */
function resolveResError(code, message) {
  switch (code) {
    case 'ECONNABORTED':
      message = `【${code}】: 请求超时！`
      break
    case 'ERR_BAD_REQUEST':
      message = `【${code}】: 未配置代理！`
      break
    case 'ERR_NETWORK':
      message = `【${code}】: 请检查网络！`
      break
    default:
      message = `【${code}】: ${message}!`
      break
  }
  return message
}
